uniapp腾讯地图JavaScript Api,H5端和原生APP端可用

您所在的位置:网站首页 uniapp 适配js uniapp腾讯地图JavaScript Api,H5端和原生APP端可用

uniapp腾讯地图JavaScript Api,H5端和原生APP端可用

2024-07-14 06:19| 来源: 网络整理| 查看: 265

        因项目需要,在uniapp中集成使用腾讯地图,为了方便维护,希望通过一套代码实现H5和APP同时可用。H5显示相对简单,APP端比较麻烦,记录下实现过程

一、集成步骤 1.使用 renderjs

script标签使用renderjs,因为JavaScript Api需要调用DOM对象,APP需要使用renderjs技术,保证script运行在webview环境,才能调用DOM对象。

2.引用地图script

导入腾讯地图JS脚本,因为腾讯地图js不是按照uniapp格式编写,所以不能直接import导入,需要包装成一个js插件,使用 Promise,js加载成功,调用resolve,js加载失败,调用reject。

创建loadJs.js 文件

function loadJs(src) {   return new Promise((resolve,reject)=>{     let script = document.createElement('script');     script.type = "text/javascript";     script.src= src;     document.body.appendChild(script);            script.onload = ()=>{       resolve();     }     script.onerror = ()=>{       reject();     }   }).catch((e) => {}) }   export default loadJs

在页面中使用

    import loadJs from "../../common/loadJs.js"          export default {         data() {             return {                              }         },         mounted(){             console.log('renderjs初始化完毕')             loadJs('https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77').then(()=>{                 // 加载成功,进行后续操作             })         },          methods: {         }     } 3.修改js,兼容uniapp

下载腾讯官网的例子,改造成uniapp兼容的格式。有两种方式,

方式一:

将官网例子中 script 封装成一个个的function,定义在 vue文件的 methods 中,这样就可以直接调用。

方式二:

将官网例子中 script 代码全部拷贝到一个js文件中,再把需要调用的 function 通过 export 关键字导出,在vue文件中进行 import 调用。

4.修改监听事件

腾讯官网例子都是web端的,点击事件都是click,H5端运行需要改成touchend,否则点击无响应

Web端

svg.addEventListener('click', this.onClick); web端用click事件

H5端

svg.addEventListener('touchend', this.onClick); // H5端用touchend事件

二、示例 腾讯官网例子

以自定义覆盖物 -> DOMOverlay 为例,实操下

DOMOverlay html, body { height: 100%; margin: 0px; padding: 0px; } #container { width: 100%; height: 100%; } var SVG_NS = 'http://www.w3.org/2000/svg'; // 自定义环状饼图 - 继承DOMOverlay function Donut(options) { TMap.DOMOverlay.call(this, options); } Donut.prototype = new TMap.DOMOverlay(); // 初始化 Donut.prototype.onInit = function(options) { this.position = options.position; this.data = options.data; this.minRadius = options.minRadius || 0; this.maxRadius = options.maxRadius || 50; }; // 销毁时需解绑事件监听 Donut.prototype.onDestroy = function() { if (this.onClick) { this.dom.removeEventListener(this.onClick); } }; // 创建DOM元素,返回一个DOMElement,使用this.dom可以获取到这个元素 Donut.prototype.createDOM = function() { let svg = document.createElementNS(SVG_NS, 'svg'); svg.setAttribute('version', '1.1'); svg.setAttribute('baseProfile', 'full'); let r = this.maxRadius; svg.setAttribute('viewBox', [-r, -r, r * 2, r * 2].join(' ')); svg.setAttribute('width', r * 2); svg.setAttribute('height', r * 2); svg.style.cssText = 'position:absolute;top:0px;left:0px;'; let donut = createDonut(this.data, this.minRadius, this.maxRadius); svg.appendChild(donut); // click事件监听 this.onClick = () => { // DOMOverlay继承自EventEmitter,可以使用emit触发事件 this.emit('click'); }; // pc端注册click事件,移动端注册touchend事件 svg.addEventListener('click', this.onClick); return svg; }; // 更新DOM元素,在地图移动/缩放后执行 Donut.prototype.updateDOM = function() { if (!this.map) { return; } // 经纬度坐标转容器像素坐标 let pixel = this.map.projectToContainer(this.position); // 使饼图中心点对齐经纬度坐标点 let left = pixel.getX() - this.dom.clientWidth / 2 + 'px'; let top = pixel.getY() - this.dom.clientHeight / 2 + 'px'; this.dom.style.transform = `translate(${left}, ${top})`; }; // 使用SVG创建环状饼图 function createDonut(data, minRadius, maxRadius) { const colorList = [ '#7AF4FF', '#67D7FF', '#52B5FF', '#295BFF' ]; let sum = data.reduce((prev, curr) => prev + curr, 0); let angle = 0; let group = document.createElementNS(SVG_NS, "g"); data.forEach((d, i) => { let delta = d / sum * Math.PI * 2; color = colorList[i], r = maxRadius, startAngle = angle, endAngle = angle + delta; angle += delta; // 对每个数据创建一个扇形 let fanShape = document.createElementNS(SVG_NS, 'path'); fanShape.setAttribute('style', `fill: ${color};`); fanShape.setAttribute('d', [ 'M0 0', `L${r * Math.sin(startAngle)} ${-r * Math.cos(startAngle)}`, `A${r} ${r} 0 ${delta > Math.PI ? 1 : 0} 1 ${r * Math.sin(endAngle)} ${-r * Math.cos(endAngle)}`, ].join(' ') + ' z'); group.appendChild(fanShape); }); // 在中心创建一个圆形 let circleShape = document.createElementNS(SVG_NS, 'circle'); circleShape.setAttribute('style', 'fill: #FFFFFF'); circleShape.setAttribute('cx', 0); circleShape.setAttribute('cy', 0); circleShape.setAttribute('r', minRadius); group.appendChild(circleShape); // 绘制文字 let textShape = document.createElementNS(SVG_NS, 'text'); textShape.setAttribute('x', 0); textShape.setAttribute('y', '0.3em'); textShape.setAttribute('text-anchor', 'middle'); textShape.innerHTML = sum; group.appendChild(textShape); return group; } window.Donut = Donut; var map; function initMap() { // 初始化地图 map = new TMap.Map("container", { zoom:12, // 设置地图缩放级别 center: new TMap.LatLng(39.984104, 116.307503) // 设置地图中心点坐标 }); let donutList = [ new Donut({ map, position: new TMap.LatLng(39.96030543872138, 116.25809083213608), data: [12, 24], minRadius: 13, maxRadius: 20 }), new Donut({ map, position: new TMap.LatLng(39.9986945980902, 116.33598362780685), data: [23, 99, 101, 400], minRadius: 25, maxRadius: 35 }), new Donut({ map, position: new TMap.LatLng(40.02906301748584, 116.25499991104516), data: [18, 41, 50], minRadius: 20, maxRadius: 28 }) ]; donutList.forEach((donut, index) => { donut.on('click', () => { console.log(`第${index}个环形图被点击,位置为${donut.position}`); }); }); } 适配后uniapp代码

主要三个文件 DOMOverlay.js、loadJs.js、map.vue

DOMOverlay.js 

一般来说先把script 全部复制到一个单独js文件,然后直接运行,运气好直接正常使用,运气不好就哪里报错改哪里,DOMOverlay.js文件修改过我都加了注释“适配uniapp修改过的”

var SVG_NS = 'http://www.w3.org/2000/svg'; // 自定义环状饼图 - 继承DOMOverlay function Donut(options) { TMap.DOMOverlay.call(this, options); } /** * ----------------适配uniapp修改过的---------------- * * 因为 TMap 对象依赖于 https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77 * 所以要封装一个方法,在加载完依赖脚本后,再运行 */ function initDonut(){ Donut.prototype = new TMap.DOMOverlay(); // 初始化 Donut.prototype.onInit = function(options) { this.position = options.position; this.data = options.data; this.minRadius = options.minRadius || 0; this.maxRadius = options.maxRadius || 50; }; // 销毁时需解绑事件监听 Donut.prototype.onDestroy = function() { if (this.onClick) { this.dom.removeEventListener(this.onClick); } }; // 创建DOM元素,返回一个DOMElement,使用this.dom可以获取到这个元素 Donut.prototype.createDOM = function() { let svg = document.createElementNS(SVG_NS, 'svg'); svg.setAttribute('version', '1.1'); svg.setAttribute('baseProfile', 'full'); let r = this.maxRadius; svg.setAttribute('viewBox', [-r, -r, r * 2, r * 2].join(' ')); svg.setAttribute('width', r * 2); svg.setAttribute('height', r * 2); svg.style.cssText = 'position:absolute;top:0px;left:0px;'; let donut = createDonut(this.data, this.minRadius, this.maxRadius); svg.appendChild(donut); // click事件监听 this.onClick = () => { // DOMOverlay继承自EventEmitter,可以使用emit触发事件 this.emit('click'); }; // ----------------适配uniapp修改过的---------------- // pc端注册click事件,移动端注册touchend事件 // svg.addEventListener('click', this.onClick); web端用click事件 svg.addEventListener('touchend', this.onClick); // H5端用touchend事件 return svg; }; // 更新DOM元素,在地图移动/缩放后执行 Donut.prototype.updateDOM = function() { if (!this.map) { return; } // 经纬度坐标转容器像素坐标 let pixel = this.map.projectToContainer(this.position); // 使饼图中心点对齐经纬度坐标点 let left = pixel.getX() - this.dom.clientWidth / 2 + 'px'; let top = pixel.getY() - this.dom.clientHeight / 2 + 'px'; this.dom.style.transform = `translate(${left}, ${top})`; }; } // 使用SVG创建环状饼图 function createDonut(data, minRadius, maxRadius) { const colorList = [ '#7AF4FF', '#67D7FF', '#52B5FF', '#295BFF' ]; let sum = data.reduce((prev, curr) => prev + curr, 0); let angle = 0; let group = document.createElementNS(SVG_NS, "g"); data.forEach((d, i) => { let delta = d / sum * Math.PI * 2; let color = colorList[i], r = maxRadius, startAngle = angle, endAngle = angle + delta; angle += delta; // 对每个数据创建一个扇形 let fanShape = document.createElementNS(SVG_NS, 'path'); fanShape.setAttribute('style', `fill: ${color};`); fanShape.setAttribute('d', [ 'M0 0', `L${r * Math.sin(startAngle)} ${-r * Math.cos(startAngle)}`, `A${r} ${r} 0 ${delta > Math.PI ? 1 : 0} 1 ${r * Math.sin(endAngle)} ${-r * Math.cos(endAngle)}`, ].join(' ') + ' z'); group.appendChild(fanShape); }); // 在中心创建一个圆形 let circleShape = document.createElementNS(SVG_NS, 'circle'); circleShape.setAttribute('style', 'fill: #FFFFFF'); circleShape.setAttribute('cx', 0); circleShape.setAttribute('cy', 0); circleShape.setAttribute('r', minRadius); group.appendChild(circleShape); // 绘制文字 let textShape = document.createElementNS(SVG_NS, 'text'); textShape.setAttribute('x', 0); textShape.setAttribute('y', '0.3em'); textShape.setAttribute('text-anchor', 'middle'); textShape.innerHTML = sum; group.appendChild(textShape); return group; } window.Donut = Donut; var map; function initMap() { // ----------------适配uniapp修改过的---------------- // 调用封装后的initDount() initDonut() // 初始化地图 map = new TMap.Map("mapContainer", { zoom:12, // 设置地图缩放级别 center: new TMap.LatLng(39.984104, 116.307503) // 设置地图中心点坐标 }); let donutList = [ new Donut({ map, position: new TMap.LatLng(39.96030543872138, 116.25809083213608), data: [12, 24], minRadius: 13, maxRadius: 20 }), new Donut({ map, position: new TMap.LatLng(39.9986945980902, 116.33598362780685), data: [23, 99, 101, 400], minRadius: 25, maxRadius: 35 }), new Donut({ map, position: new TMap.LatLng(40.02906301748584, 116.25499991104516), data: [18, 41, 50], minRadius: 20, maxRadius: 28 }) ]; donutList.forEach((donut, index) => { donut.on('click', () => { console.log(`第${index}个环形图被点击,位置为${donut.position}`); alert(`第${index}个环形图被点击,位置为${donut.position}`) }); }); } /** * ----------------适配uniapp修改过的---------------- * 导出initMap方法 */ export { initMap } loadJs.js

用来加载第三方js

function loadJs(src) {   return new Promise((resolve,reject)=>{     let script = document.createElement('script');     script.type = "text/javascript";     script.src= src;     document.body.appendChild(script);            script.onload = ()=>{       resolve();     }     script.onerror = ()=>{       reject();     }   }).catch((e) => {}) }   export default loadJs map.vue export default { data() { return { } }, mounted() { } } import loadJs from "../../common/loadJs.js" // 导入适配后的 DOMOverlay.js import {initMap} from "../../common/DOMOverlay.js" export default { data() { return { } }, mounted(){ console.log("mounted") loadJs('https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77').then(()=>{ // 调用初始化地图方法 initMap() }) }, methods: { }, created() { } } 三、适配效果

APP运行效果图,与官网一致



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3